using Engine;
using Engine.Graphics;
using Engine.ObjectManager;
using Scenario_Editor.RoadBuilder;
using Scenario_Editor.Windows;
using SharpDX;
using SharpDX.Direct3D11;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace Scenario_Editor.Tools
{
    public partial class RoadV2 : UserControl, IRenderableObject
    {
        #region Private Fields

        private bool duringUpdate = false;
        private Engine.Engine engine;
        private System.Drawing.Point lastMouesPositionOnScreen;
        private LoadingWindow loadingWindow;
        private bool moveTangent = false;
        private bool numericTextboxesChanges = false;
        private bool pluginChanges = false;
        private RoadManager roadBuilder;

        #endregion Private Fields

        #region Public Constructors

        public RoadV2()
        {
            InitializeComponent();
            tooltipLockedStreetnode.IsBalloon = true;
            this.tooltipLockedStreetnode.SetToolTip(this.checkBox_LockStreetpoint, "Streetpoint locked!");
        }

        #endregion Public Constructors

        #region Private Destructors

        ~RoadV2()
        {
            this.loadingWindow.Dispose();
            this.loadingWindow = null;
            this.roadBuilder.Dispose();
        }

        #endregion Private Destructors

        #region Public Delegates

        public delegate void RoadManagerChangedEventHandler(object sender, EventArgs e);

        #endregion Public Delegates

        #region Public Properties

        public bool MoveTangent
        {
            get { return moveTangent; }
            set { moveTangent = value; }
        }

        public bool RecalculateSelectedStreet
        {
            set
            {
                this.cb_reverseSpline.Checked = value;
            }
        }

        #endregion Public Properties

        #region Internal Properties

        internal RoadManager RoadBuilder
        {
            get
            {
                return roadBuilder;
            }
            set
            {
                roadBuilder = value;
            }
        }

        #endregion Internal Properties

        #region Public Methods

        public void LoadFromFile(string fileName)
        {
            while (this.RoadBuilder.RoadArray.Count > 0)
            {
                this.RoadBuilder.DeleteRoadPiece(this.RoadBuilder.RoadArray[0].ID);
            }
            this.RoadBuilder.Dispose();

            this.RoadBuilder = RoadManager.FromFile(fileName, this.RoadBuilder.AddinManager, this.engine);
            this.RoadBuilder.UpdateAllRoads(true, null);
            this.RoadBuilder.LockAllStreetpoint();
        }

        public void Render(int renderStep)
        {
            this.roadBuilder.Render(renderStep);
        }

        public void RoadManagerChanged(object sender, EventArgs e)
        {
            if (this.roadBuilder != null)
            {
                this.roadBuilder.SelectedStreetPointChanged -= OnStreetNodeChange;
                this.roadBuilder.SelectedTangentNodeChanged -= OnTangentNodeChange;
            }

            this.roadBuilder = sender as RoadManager;

            if (this.roadBuilder != null)
            {
                UpdateAddinList();
                this.RoadBuilder.UpdateAllRoads(false, this.loadingWindow);

                this.roadBuilder.SelectedStreetPointChanged += OnStreetNodeChange;
                this.roadBuilder.SelectedTangentNodeChanged += OnTangentNodeChange;
            }
        }

        public void Save(string filename)
        {
            this.RoadBuilder.ToFile(filename, this.RoadBuilder.AddinManager);
        }

        #endregion Public Methods

        #region Internal Methods

        internal new void Dispose()
        {
            this.roadBuilder.Dispose();
        }

        internal void Export(ref Scenario_Editor.Exporter.ExportMesh export)
        {
            for (int i = 0; i < this.RoadBuilder.RoadArray.Count; i++)
            {
                export.AddMeshObject(this.RoadBuilder.RoadArray[i].mesh);//.Export(ref export);
            }
        }

        internal void ExportCrossroads(ref Scenario_Editor.Exporter.ExportMesh export)
        {
            for (int i = 0; i < this.RoadBuilder.streetPoint.Count; i++)
            {
                if (this.RoadBuilder.streetPoint[i].usedbyID.Count > 2)
                {
                    if (this.RoadBuilder.streetPoint[i].CrossroadMesh != null)
                    {
                        export.AddMeshObject(this.RoadBuilder.streetPoint[i].CrossroadMesh);
                    }
                }
            }
        }

        internal Control GetUserControl(int index)
        {
            return this.RoadBuilder.AddinManager.Addins[index].GetUserControl();
        }

        /// <summary>
        /// Loads the Addins and gives the textures to it.
        /// </summary>
        /// <param name="engine">The engine.</param>
        /// <param name="materialManager">The material manager.</param>
        /// <param name="shaderManager">The shader manager.</param>
        /// <param name="addinFolder">The addin folder.</param>
        /// <param name="maxRoadLength">Length of the max road.</param>
        internal void Initialize(Engine.Engine engine, float maxRoadLength, ITerrain iTerrain)
        {
            this.engine = engine;
            this.RoadBuilder.iTerrain = iTerrain;

            GeoMath.maximumLengthOfMiddleLine = maxRoadLength;
        }

        internal void OnLoadingWindowChange(object sender, EventArgs e)
        {
            this.loadingWindow = (LoadingWindow)sender;
        }

        internal void UseThisTool(Engine.Engine mdxPanel, Panel panel, CameraControl cameraControl, Vector3 position, bool weldStreetToTerrain, bool CursorIsIn3dPanel, NumericUpDown zHeight, bool getHeightFromTerrain)
        {
            bool mouseMoved = true;// (lastMouesPositionOnScreen != this.engine.Grafic.MousePositionOnRenderControl) ? true : false;
            var device = mdxPanel.Device;
            var mouse = mdxPanel.Mouse;
            var keyboard = mdxPanel.Keyboard;
            var camera = cameraControl.Camera;
            var cameraTargetPosition = mdxPanel.Camera.CameraTartget;
            if (this.roadBuilder.SelectedStreetpoint > -1)
            {
                float distanceMouseMove = 3.0f;
                Vector3 spPos = this.roadBuilder.streetPoint[this.roadBuilder.SelectedStreetpoint].pos;
                Vector3 lastMouse = new Vector3(lastMouesPositionOnScreen.X, 0, lastMouesPositionOnScreen.Y);
                var positionOnScreen = this.engine.Grafic.GetScreenCoordinate(spPos);
                if (GeoMath.DistanceBtw2Points(new Vector3(positionOnScreen.X, 0, positionOnScreen.Y), lastMouse) < distanceMouseMove)
                    mouseMoved = false;

                if (mouseMoved)
                    if (this.roadBuilder.selectedTangent > -1)
                    {
                        Vector3 absoluteTangentPosition = this.roadBuilder.streetPoint[this.roadBuilder.SelectedStreetpoint].GetAbsoluteTangentPosition(this.roadBuilder.selectedTangent);
                        positionOnScreen = this.engine.Grafic.GetScreenCoordinate(absoluteTangentPosition);

                        var distance = GeoMath.DistancePlanar(new Vector3(positionOnScreen.X, 0, positionOnScreen.Y), lastMouse);

                        if (distance < distanceMouseMove)
                            mouseMoved = false;
                        //else
                        //    RenderText.DrawString("Distance : " + distance.ToString(), absoluteTangentPosition, new Color4(1, 0, 0, 1), this.engine,0,0);
                    }
            }
            lastMouesPositionOnScreen = this.engine.Grafic.MousePositionOnRenderControl;

            if (CursorIsIn3dPanel)
            {
                if (buttonNewRoad.Checked)
                {
                    if (mouse.ButtonLeftPressingStarted)
                    {
                        int startStreetpoint = this.RoadBuilder.GetNearestStreetpoint(cameraTargetPosition, engine.Grafic.MousePositionOnRenderControl, 15);
                        this.RoadBuilder.AddTrackPiece(position, (float)this.numericUpDown_fall.Value, startStreetpoint, cameraTargetPosition, panel, this.comboBox_usedPlugin.SelectedIndex, true);
                    }
                    else if (mouse.ButtonL && mouse.HasMovedWhilePressingL && (mouseMoved))
                    {
                        int streepointId = -1;
                        int tangentId = -1;
                        Vector3 tangent = Vector3.Zero;
                        if (this.RoadBuilder.selectedRoadPieceID > -1)
                        {
                            int roadId = this.RoadBuilder.RoadArray[this.RoadBuilder.RoadArray.Count - 1].ID;
                            streepointId = this.RoadBuilder.RoadArray[this.RoadBuilder.RoadArray.Count - 1].SPOne;
                            tangent = -(position - this.RoadBuilder.streetPoint[streepointId].pos);

                            for (int i = 0; i < this.RoadBuilder.streetPoint[streepointId].usedbyID.Count; i++)
                            {
                                if (this.RoadBuilder.streetPoint[streepointId].usedbyID.Count == 1)
                                {
                                    int roadId2 = this.RoadBuilder.streetPoint[streepointId].usedbyID[i];
                                    this.RoadBuilder.streetPoint[streepointId].SetTangent(roadId2, tangent);
                                    tangentId = i;
                                    this.RoadBuilder.UpdateStreetpoint(streepointId, weldStreetToTerrain);
                                    break;
                                }
                                else
                                {
                                    int roadId2 = this.RoadBuilder.streetPoint[streepointId].usedbyID[i];
                                    if (roadId != this.RoadBuilder.streetPoint[streepointId].usedbyID[i])
                                    {
                                        this.RoadBuilder.streetPoint[streepointId].SetTangent(roadId2, -tangent);
                                    }
                                    else
                                    {
                                        this.RoadBuilder.streetPoint[streepointId].SetTangent(roadId2, tangent);
                                    }
                                    tangentId = i;
                                }
                                this.RoadBuilder.UpdateStreetpoint(streepointId, weldStreetToTerrain);
                            }
                        }

                        this.RoadBuilder.MoveSelectedStreetpointStreetpoint(position, true, weldStreetToTerrain);
                    }
                    else if (!mouse.ButtonL && (mouseMoved))
                    {
                        Vector3 positionNew = position;

                        int node = this.RoadBuilder.GetNearestStreetpoint(cameraTargetPosition, this.engine.Grafic.MousePositionOnRenderControl, 13);

                        if (node > -1)
                        {
                            positionNew = this.RoadBuilder.GetPositionSP(node);
                        }

                        this.RoadBuilder.MoveSelectedStreetpointStreetpoint(positionNew, true, weldStreetToTerrain);
                    }

                    if (mouse.ButtonRreleased & !mouse.HasMovedWhilePressingR)
                    {
                        this.RoadBuilder.DeleteLastRoadPiece();
                    }
                }

                if (mouse.ButtonRreleased & !mouse.HasMovedWhilePressingR)
                {
                    this.RoadBuilder.DeselectAll();
                }
                else if (mouse.ButtonR)
                {
                    if (getHeightFromTerrain | (this.RoadBuilder.SelectedStreetpoint < 0))
                    {
                        mdxPanel.Camera.MoveUpDown(mouse.AxisY);
                        mdxPanel.Camera.MoveXY(-mouse.AxisX, 0.0f);
                    }
                    else
                    {
                        zHeight.Value += (decimal)-mouse.AxisY;
                    }
                }

                if (mouse.ButtonM)// If middle Mouse-Button is pressed
                {
                    mdxPanel.Camera.RotateTargetAroundCamera(-mouse.AxisX, -mouse.AxisY);
                }
                if (mouse.AxisZ != 0)// ZOOM in  and out
                {
                    mdxPanel.Camera.MoveForward(mouse.AxisZ);
                }

                if (buttonMoveRoad.Checked)
                {
                    if (mouse.ButtonLeftPressingStarted)
                    {
                        this.RoadBuilder.selectedTangent = this.RoadBuilder.GetTangentFromStreetpoint(cameraTargetPosition, this.engine.Grafic.MousePositionOnRenderControl, 19, this.RoadBuilder.SelectedStreetpoint);
                        if (this.RoadBuilder.selectedTangent > -1)
                        {
                            moveTangent = true;
                        }
                        else
                        {
                            this.RoadBuilder.SelectedStreetpoint = -1;
                            this.RoadBuilder.SelectedStreetpoint = this.RoadBuilder.GetNearestStreetpoint(cameraTargetPosition, this.engine.Grafic.MousePositionOnRenderControl, 19);
                            if (this.RoadBuilder.SelectedStreetpoint > -1)
                            {
                                moveTangent = false;

                                position = this.RoadBuilder.streetPoint[this.RoadBuilder.SelectedStreetpoint].pos;
                                zHeight.Value = (decimal)position.Y;
                                Cursor.Position = panel.PointToScreen(this.engine.Grafic.GetScreenCoordinate(this.RoadBuilder.streetPoint[this.RoadBuilder.SelectedStreetpoint].pos));
                            }
                        }
                    }
                    else
                    {
                        if (this.RoadBuilder.SelectedStreetpoint > -1)
                        {
                            zHeight.Value = (decimal)this.RoadBuilder.streetPoint[this.RoadBuilder.SelectedStreetpoint].pos.Y;

                            if ((mouse.ButtonL && mouse.HasMovedWhilePressingL) || mouse.ButtonLreleased)
                            {
                                if (moveTangent)
                                {
                                    if (mouse.HasMovedWhilePressingL && (mouseMoved))
                                    {
                                        if (mouse.ButtonLreleased)
                                        {
                                            this.RoadBuilder.MoveTangentVector(position, this.RoadBuilder.SelectedStreetpoint, this.RoadBuilder.selectedTangent, true);
                                        }
                                        else
                                        {
                                            this.RoadBuilder.MoveTangentVector(position, this.RoadBuilder.SelectedStreetpoint, this.RoadBuilder.selectedTangent, weldStreetToTerrain);
                                        }
                                    }
                                }
                                else
                                {
                                    if (mouse.HasMovedWhilePressingL && (mouseMoved))
                                    {
                                        try
                                        {
                                            if (mouse.ButtonLreleased)
                                            {
                                                this.RoadBuilder.MoveSelectedStreetpointStreetpoint(position, false, true);
                                            }
                                            else
                                            {
                                                this.RoadBuilder.MoveSelectedStreetpointStreetpoint(position, false, weldStreetToTerrain);
                                            }

                                            this.tooltipLockedStreetnode.Hide(this.checkBox_LockStreetpoint);
                                        }
                                        catch (LockedException ex)
                                        {
                                            // Show tooltip
                                            this.tooltipLockedStreetnode.Show("Steetpoint locked", this.checkBox_LockStreetpoint);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                if (mouse.ButtonRreleased & !mouse.HasMovedWhilePressingR)
                {
                    this.RoadBuilder.SelectedStreetpoint = -1;
                }
                else if (mouse.ButtonR || mouse.ButtonRreleased)
                {
                    if (getHeightFromTerrain)
                    {
                        if (mouse.ButtonR)// If right Mouse-Button is pressed
                        {
                            mdxPanel.Camera.MoveUpDown(mouse.AxisY);
                            mdxPanel.Camera.MoveXY(-mouse.AxisX, 0.0f);
                        }
                    }
                    else
                    {
                        if (this.RoadBuilder.SelectedStreetpoint > -1)
                        {
                            position = this.RoadBuilder.streetPoint[this.RoadBuilder.SelectedStreetpoint].pos;
                            numericUpDown_positionY.Value -= (decimal)(mouse.AxisY);// / 10.0f);
                            zHeight.Value = (decimal)numericUpDown_positionY.Value;
                            position.Y = (float)numericUpDown_positionY.Value;
                        }
                    }
                }
            }

            //Delete selected Streetpoint
            if (buttonDeleteRoad.Checked)
            {
                buttonDeleteRoad.Checked = false;
                if (this.RoadBuilder.SelectedStreetpoint > -1)
                {
                    if (this.RoadBuilder.selectedTangent > -1) // Delete only the selected roadpiece
                    {
                        this.RoadBuilder.DeleteRoadPiece(this.RoadBuilder.streetPoint[this.RoadBuilder.SelectedStreetpoint].usedbyID[this.RoadBuilder.selectedTangent]);
                    }
                    else // Delete the entire streepoint with all its connected roadpieces.
                    {
                        List<int> roadpiecewhichShouldDeleted = new List<int>();
                        for (int i = 0; i < this.RoadBuilder.streetPoint[this.RoadBuilder.SelectedStreetpoint].usedbyID.Count; i++)
                        {
                            roadpiecewhichShouldDeleted.Add(this.RoadBuilder.streetPoint[this.RoadBuilder.SelectedStreetpoint].usedbyID[i]);
                        }

                        for (int i = 0; i < roadpiecewhichShouldDeleted.Count; i++)
                        {
                            this.RoadBuilder.DeleteRoadPiece(roadpiecewhichShouldDeleted[i]);
                        }
                    }

                    this.RoadBuilder.DeselectAll();
                }
            }
            if (cb_reverseSpline.Checked)
            {
                cb_reverseSpline.Checked = false;
                this.RoadBuilder.UpdateRoad(this.roadBuilder.ReverseSpline(this.RoadBuilder.SelectedStreetpoint, this.RoadBuilder.selectedTangent), true);
            }

            UpdateStreetinfo(device, weldStreetToTerrain);
        }

        #endregion Internal Methods

        #region Private Methods

        private void buttonNewRoad_CheckedChanged(object sender, EventArgs e)
        {
            this.RoadBuilder.DeselectAll();
        }

        private void checkBox_LockStreetpoint_CheckedChanged(object sender, EventArgs e)
        {
            if (this.RoadBuilder.SelectedStreetpoint > -1)
            {
                Streetpoint streetpoint = this.RoadBuilder.streetPoint[this.RoadBuilder.SelectedStreetpoint];
                streetpoint.Locked = checkBox_LockStreetpoint.Checked;
                this.RoadBuilder.streetPoint[this.RoadBuilder.SelectedStreetpoint] = streetpoint;
            }
        }

        private void comboBox_streetpoints_SelectionChangeCommitted(object sender, EventArgs e)
        {
            if (!this.RoadBuilder.duringUpdate && this.RoadBuilder.SelectedStreetpoint > -1)
            {
                int selectedCombovalue = comboBox_streetpoints.SelectedIndex;
                if (selectedCombovalue > -1)
                {
                    this.RoadBuilder.selectedTangent = selectedCombovalue;
                    int roadID = this.RoadBuilder.streetPoint[this.RoadBuilder.SelectedStreetpoint].usedbyID[selectedCombovalue];
                    int arrayposition = this.RoadBuilder.GetArrayPostionFromRoadID(roadID);
                    int usedPlugin = RoadBuilder.RoadArray[arrayposition].usedPlugin;
                    this.RoadBuilder.AddinManager.Addins[usedPlugin].SetProperties(RoadBuilder.RoadArray[arrayposition].PropertiesRoads);
                    this.RoadBuilder.AddinManager.Addins[usedPlugin].SetTrafficData(RoadBuilder.RoadArray[arrayposition].Traffic);
                }
            }
        }

        private void comboBox_usedPlugin_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.SuspendLayout();
            //Get the Control from Addin
            Control control = GetUserControl(comboBox_usedPlugin.SelectedIndex);
            var site = control.Size;

            control.SuspendLayout();

            // Shrink control in width for scrollbar if needed.
            if (control.Size.Height > panel_PluginControl.Size.Height)
                control.Size = new System.Drawing.Size(this.panel_PluginControl.Size.Width - System.Windows.Forms.SystemInformation.VerticalScrollBarWidth, control.Size.Height);
            else
                control.Size = new System.Drawing.Size(this.panel_PluginControl.Size.Width, control.Size.Height);

            this.panel_PluginControl.SuspendLayout();
            this.panel_PluginControl.Controls.Clear();
            this.panel_PluginControl.Controls.Add(control);
            this.panel_PluginControl.AutoScroll = true;
            site = this.panel_PluginControl.Size;

            if (this.RoadBuilder.SelectedStreetpoint > -1)
            {
                this.pluginChanges = true;
            }
            control.ResumeLayout();
            this.panel_PluginControl.ResumeLayout();
            this.ResumeLayout();
        }

        private void numericUpDown_ValueChanged(object sender, EventArgs e)
        {
            numericTextboxesChanges = true;
        }

        private void OnStreetNodeChange(object sender, EventArgs e)
        {
            int streetpointId = (int)sender;

            //Update the Control PAnel
            this.comboBox_streetpoints.Items.Clear();

            if (streetpointId > -1)
            {
                Streetpoint streetpoint = this.roadBuilder.GetStreetNodeById(streetpointId);
                this.checkBox_LockStreetpoint.Checked = streetpoint.Locked;
                //adds all RoadIDs to the combobox
                for (int id = 0; id < streetpoint.usedbyID.Count; id++)
                {
                    this.comboBox_streetpoints.Items.Add(streetpoint.usedbyID[id]);
                }

                //Update selected Addin
                if (streetpoint.usedbyID.Count > 2)
                {
                    this.comboBox_usedPlugin.SelectedIndex = streetpoint.UsedPlugin;
                }
                else
                {
                    // Activate the right Panel in the Addin.
                    if (streetpoint.usedbyID.Count > 0)
                    {
                        int index = this.roadBuilder.GetRoadNRinArray(streetpoint.usedbyID[0]);
                        this.roadBuilder.AddinManager.Addins[this.roadBuilder.RoadArray[index].usedPlugin].SetRightPanel(streetpoint.usedbyID.Count);
                        this.comboBox_usedPlugin.SelectedIndex = this.roadBuilder.RoadArray[index].usedPlugin;
                    }
                }
            }
            else
            {
                comboBox_streetpoints.Items.Clear();
                comboBox_streetpoints.Text = string.Empty;
                this.comboBox_streetpoints.SelectedIndex = -1;
            }
        }

        private void OnTangentNodeChange(object sender, EventArgs e)
        {
            int SelectedTangent = (int)sender;

            if (this.RoadBuilder.SelectedStreetpoint > -1)
            {
                Streetpoint streetNode = this.roadBuilder.GetStreetNodeById(this.roadBuilder.SelectedStreetpoint);
                if (SelectedTangent > -1)
                {
                    int roadID = streetNode.usedbyID[SelectedTangent];
                    Roadpiece roadPiece = this.roadBuilder.GetRoadpieceById(roadID);
                    int usedPlugin = roadPiece.usedPlugin;
                    int selectedPlugin = comboBox_usedPlugin.SelectedIndex;
                    if (usedPlugin == selectedPlugin)
                    {
                        this.roadBuilder.AddinManager.Addins[usedPlugin].SetProperties(roadPiece.PropertiesRoads);
                        this.roadBuilder.AddinManager.Addins[usedPlugin].SetTrafficData(roadPiece.Traffic);
                    }
                    else
                    {
                        comboBox_usedPlugin.SelectedIndex = usedPlugin;
                        this.roadBuilder.AddinManager.Addins[usedPlugin].SetProperties(roadPiece.PropertiesRoads);
                        this.roadBuilder.AddinManager.Addins[usedPlugin].SetTrafficData(roadPiece.Traffic);
                    }
                    if (this.comboBox_streetpoints.Items.Count > SelectedTangent && this.comboBox_streetpoints.Items.Count > -1)
                        comboBox_streetpoints.SelectedIndex = SelectedTangent;
                }
            }
            else
            {
                comboBox_streetpoints.Items.Clear();
                comboBox_streetpoints.Text = string.Empty;
            }
        }

        private void SelectTextOnEnter(object sender, EventArgs e)
        {
            if (sender.GetType() == typeof(NumericUpDown))
            {
                NumericUpDown numericUpDown = sender as NumericUpDown;
                numericUpDown.Select(0, numericUpDown.ToString().Length);
            }
        }

        private void UpdateAddinList()
        {
            comboBox_usedPlugin.DataSource = this.RoadBuilder.AddinManager.GetPluginNames();

            if (comboBox_usedPlugin.SelectedIndex < 0)
            {
                if (comboBox_usedPlugin.Items.Count > 0)
                {
                    comboBox_usedPlugin.SelectedIndex = 0;
                }
            }
        }

        private void UpdateStreetinfo(Device device, bool weldToTerrain)
        {
            if (this.RoadBuilder.SelectedStreetpoint > -1)
            {
                int sp = this.RoadBuilder.SelectedStreetpoint;

                //Update the numeric textboxes
                numericUpDown_positionX.Enabled = true;
                numericUpDown_positionY.Enabled = true;
                numericUpDown_positionZ.Enabled = true;

                //if Textboxes changed
                if (numericTextboxesChanges)
                {
                    if (!this.duringUpdate)
                    {
                        try
                        {
                            this.duringUpdate = true;
                            Vector3 position = new Vector3((float)numericUpDown_positionX.Value, (float)numericUpDown_positionY.Value, (float)numericUpDown_positionZ.Value);
                            Streetpoint stp = this.RoadBuilder.streetPoint[sp];
                            stp.SetRoadInclinationAngle((float)this.numericUpDown_fall.Value);
                            this.RoadBuilder.streetPoint[sp] = stp;

                            this.RoadBuilder.MoveSelectedStreetpointStreetpoint(position, false, weldToTerrain);
                        }
                        catch (LockedException ex)
                        {
                            //tooltipLockedStreetnode.Show("Streetpoint locked. You can uncheck the Checkbox if you want to move the streetnode!", this.checkBox_LockStreetpoint);
                        }

                        numericUpDown_positionX.Value = (decimal)this.RoadBuilder.streetPoint[sp].pos.X;
                        numericUpDown_positionY.Value = (decimal)this.RoadBuilder.streetPoint[sp].pos.Y;
                        numericUpDown_positionZ.Value = (decimal)this.RoadBuilder.streetPoint[sp].pos.Z;

                        numericTextboxesChanges = false;
                        duringUpdate = false;
                    }
                }
                else
                {
                    numericUpDown_positionX.Value = (decimal)this.RoadBuilder.streetPoint[sp].pos.X;
                    numericUpDown_positionY.Value = (decimal)this.RoadBuilder.streetPoint[sp].pos.Y;
                    numericUpDown_positionZ.Value = (decimal)this.RoadBuilder.streetPoint[sp].pos.Z;
                    this.numericUpDown_fall.Value = (decimal)this.RoadBuilder.streetPoint[sp].RoadInclinationAngle;
                }

                //Compare the properties and materials and usedPlugin with selected street. If they are different the street will be updated
                int selectedPlugin = comboBox_usedPlugin.SelectedIndex;

                if (this.RoadBuilder.SelectedStreetpoint > -1)
                {
                    //Set new pluginProperties.
                    //Change the usedPlugin in RoadPiece, Change the Properties from streetpoint

                    if (this.RoadBuilder.selectedTangent > -1)
                    {
                        if (this.RoadBuilder.AddinManager.Addins[selectedPlugin].HasPropertiesChanged() & !pluginChanges)
                        {
                            int roaID = this.RoadBuilder.streetPoint[this.RoadBuilder.SelectedStreetpoint].usedbyID[this.RoadBuilder.selectedTangent];
                            int index = this.RoadBuilder.GetRoadNRinArray(roaID);
                            Roadpiece rp = RoadBuilder.RoadArray[index];
                            Streetpoint sp1 = this.RoadBuilder.streetPoint[rp.SPOne];
                            Streetpoint sp2 = this.RoadBuilder.streetPoint[rp.SPTwo];

                            rp.PropertiesRoads = this.RoadBuilder.AddinManager.Addins[rp.usedPlugin].GetProperties();
                            rp.Traffic = this.RoadBuilder.AddinManager.Addins[rp.usedPlugin].GetTrafficData(rp.PropertiesRoads);

                            RoadBuilder.RoadArray[index] = rp;
                            this.RoadBuilder.UpdateRoad(roaID, weldToTerrain);
                        }

                        if (pluginChanges)
                        {
                            pluginChanges = false;

                            int roaID = this.RoadBuilder.streetPoint[this.RoadBuilder.SelectedStreetpoint].usedbyID[this.RoadBuilder.selectedTangent];
                            int index = this.RoadBuilder.GetRoadNRinArray(roaID);
                            Roadpiece rp = this.RoadBuilder.RoadArray[index];

                            rp.usedPlugin = comboBox_usedPlugin.SelectedIndex;
                            rp.PropertiesRoads = this.RoadBuilder.AddinManager.Addins[rp.usedPlugin].GetProperties();
                            rp.Traffic = this.RoadBuilder.AddinManager.Addins[rp.usedPlugin].GetTrafficData(rp.PropertiesRoads);
                            this.RoadBuilder.RoadArray[index] = rp;
                            this.RoadBuilder.UpdateRoad(roaID, weldToTerrain);
                        }
                    }
                    else
                    {
                        if (this.RoadBuilder.AddinManager.Addins[selectedPlugin].HasPropertiesChanged() & !pluginChanges)
                        {
                            Streetpoint streetpoint = this.RoadBuilder.streetPoint[this.RoadBuilder.SelectedStreetpoint];
                            streetpoint.propertiesCR = this.RoadBuilder.AddinManager.Addins[streetpoint.UsedPlugin].GetPropertiesCR(streetpoint.usedbyID.Count);
                            this.RoadBuilder.streetPoint[this.RoadBuilder.SelectedStreetpoint] = streetpoint;
                            this.RoadBuilder.UpdateStreetpoint(this.RoadBuilder.SelectedStreetpoint, weldToTerrain);
                        }

                        if (pluginChanges)
                        {
                            pluginChanges = false;
                            Streetpoint streetpoint = this.RoadBuilder.streetPoint[this.RoadBuilder.SelectedStreetpoint];
                            streetpoint.UsedPlugin = comboBox_usedPlugin.SelectedIndex;
                            streetpoint.propertiesCR = this.RoadBuilder.AddinManager.Addins[streetpoint.UsedPlugin].GetPropertiesCR(streetpoint.usedbyID.Count);
                            this.RoadBuilder.streetPoint[this.RoadBuilder.SelectedStreetpoint] = streetpoint;
                            this.RoadBuilder.UpdateStreetpoint(this.RoadBuilder.SelectedStreetpoint, weldToTerrain);
                        }
                    }
                }
            }
            else
            {
                comboBox_streetpoints.Items.Clear();
                comboBox_streetpoints.Text = "";

                numericUpDown_positionX.Enabled = false;
                numericUpDown_positionY.Enabled = false;
                numericUpDown_positionZ.Enabled = false;
                //this.numericUpDown_fall.Enabled = false;

                numericUpDown_positionX.Value = 0;
                numericUpDown_positionY.Value = 0;
                numericUpDown_positionZ.Value = 0;
                //this.numericUpDown_fall.Value = 0;

                this.numericTextboxesChanges = false;
            }
        }

        #endregion Private Methods
    }
}